package ba.unsa.etf.pikks.LoC;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import ba.unsa.etf.pikks.objekti.PredProcesiranje;


public class LOC  {

	public HashMap<String,Integer> LocCounterManager(File fileName) throws Exception {
		
		// Open File
		File myFileName = fileName;
		
		//Create the parse object
		PredProcesiranje fp = new PredProcesiranje(myFileName);
		
		//Temp Hash Map
		HashMap<String,Integer> myReturnTable = null;
		
		myReturnTable = new HashMap<String, Integer>();
		
		myReturnTable.put("Class", LocCounterFile(myFileName,1, 999999999)); 
		
		//Line Index
		int index=1;
		int methodInitialLoc=1;
		int methodFinalLoc=0;

		//cycle by all methods present in the class
		for (int i=1;i<=fp.methodMap.size();i++) {
			//Identify the start line of the next method
			while (fp.methodMap.get(index)==null && index <= fp.line_number) {
			  index++;
			}  
			methodInitialLoc = index;
			
			//go to last line of the method
			index++;
			while (fp.methodMap.get(index)==null && index <= fp.line_number) {
				  index++;
				}
			methodFinalLoc = index-1;
			
			//count Lines
			String methodName = fp.methodMap.get(methodInitialLoc);
			if ( methodName.indexOf( " class " ) == -1 ) {
				myReturnTable.put(methodName,
				LocCounterFile(myFileName,methodInitialLoc,methodFinalLoc));
			}
		}		
		return myReturnTable; 
	}
	
	private int LocCounterFile(File fileName, int startPosition, int endPosition) throws Exception {
		
		// Variables Declaration
		String 		code_line = null;
		String 		message_line = null;
		Boolean 	comment_line = false;
		Boolean		blank_line = false;
		Boolean		executable_line = false;
		Boolean     comment_in_progress = false;
		int 		loc = 0;
		int 		line_number = 0;

		final String[] keyword_list = {"abstract","continue","for","new","switch","default","goto","package","synchronized",
								"boolean","do","if","private","this","break","double","implements","protected","throw",
								"byte","else","import","public","throws","case","instanceof","return","transient",
								"catch","extends","int","short","try","char","final","interface","static","void",
								"class","finally","long","volatile","float","native","super","while"};

		final String[] reserved_ch_list = {"!=","==",">=","<=","{","}"};


		// Open File
		File myFileName = fileName; //default file: src\\Program2A.java
		//File myFileName = new File("src\\Program2B.java");
		Scanner diskScanner = new Scanner(myFileName);
		//System.out.println("Information "+myFileName.getAbsolutePath()+":");
		//System.out.println("---------------------------------------------");

		line_number=0;

		while (diskScanner.hasNext()) {

			// reset inside while
			comment_line = false;
			blank_line = false;
			executable_line = false;
			message_line="";
			line_number++;
			// GetLine
			code_line = diskScanner.nextLine().trim();


			//check if its a blank line
			if (code_line.length()==0 || code_line==";") {
				message_line = message_line + "BlankLine,";
				blank_line = true;
			}

			// if it isn't a blank line and have more than 2 characters or equal..
			if (!blank_line && code_line.length()>=2) {

				// if its a comment begin...
				if (code_line.indexOf("/"+"*") == 0) {
				message_line = message_line + "CommentLine,";
				comment_line = true;
				comment_in_progress = true;
				}

				// if its a line comment...
				if (code_line.indexOf("//") == 0) {
					message_line = message_line + "CommentLine,";
					comment_line = true;
				}

				// if its a comment end...
				if (code_line.indexOf("*"+"/") >= 0) {
					message_line = message_line + "CommentLine,";
					comment_line = true;
					comment_in_progress = false;
				}
			}
			if (comment_in_progress) {
				message_line = message_line + "CommentLine,";
			}

			// If it isn't comment or blank lines then ...
			if (!comment_line & !comment_in_progress & !blank_line) {

				//Test End characters
				if (code_line.indexOf(";") >= 0) {
					executable_line	= true;
				}

				//Test keywords
				for (int j=0; j<46; j++) {
					if ((code_line.toUpperCase()).indexOf(keyword_list[j].toUpperCase()) >= 0) {
					executable_line = true;
					}
				}

				//Test Reserved Characters
				for (int j=0; j<6; j++) {
					if ((code_line.toUpperCase()).indexOf(reserved_ch_list[j].toUpperCase()) >= 0) {
					executable_line = true;
					}
				}

				if (executable_line) {
					
					// if inside countable position
					if (line_number>=startPosition && line_number<=endPosition) {
						loc++;
					}
				};// else {
					//System.out.println("["+line_number+"] non-executable line");
				//}

			};// else { // Blanks and Comments Lines
				//System.out.println("["+line_number+"]"+ message_line+" Current LOC="+loc);
			//}

		}
		//System.out.println("LOC="+loc);
		return loc;
	}
	
}
